﻿using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CodeSystem
{
    public partial class MainForm : Form
    {
        private TimerTaskForm _timerTaskForm;
        private ILogger<MainForm> _logger;

        //这里在窗体上没有拖拽一个NotifyIcon控件，而是在这里定义了一个变量  
        private NotifyIcon notifyIcon = null;

        public MainForm(TimerTaskForm timerTaskForm, ILogger<MainForm> logger)
        {
            _timerTaskForm = timerTaskForm;
            _logger = logger;
            InitializeComponent();
            //调用初始化托盘显示函数  
            InitialTray();
            CheckAutoStartStatus();
        }

        private void btn_Conn_Click(object sender, EventArgs e)
        {
            if (txt_Ip.Text.Trim() == "")
            {
                MessageBox.Show("请输入数据库IP！");
            }
            if (txt_Port.Text.Trim() == "")
            {
                MessageBox.Show("请输入数据库端口！");
            }
            if (txt_User.Text.Trim() == "")
            {
                MessageBox.Show("请输入数据库用户名！");
            }
            if (txt_Pwd.Text.Trim() == "")
            {
                MessageBox.Show("请输入数据库密码！");
            }
            if (txt_DataBaseName.Text.Trim() == "")
            {
                MessageBox.Show("请输入数据库名称！");
            }
            SQLHelper.str = "server=" + txt_Ip.Text.Trim() + ";database=" + txt_DataBaseName.Text.Trim() + ";uid=" + txt_User.Text.Trim() + ";pwd=" + txt_Pwd.Text.Trim();
            DataTable dt = SQLHelper.GetTable("select * from sys.tables");
            lv_tables.Columns.Clear();
            lv_tables.Items.Clear();
            lv_tables.Columns.Add("表名", 200);
            foreach (DataRow dr in dt.Rows)
            {
                lv_tables.Items.Add(dr["name"].ToString());
            }
        }

        private void txt_Ip_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (sender is TextBox)
            {
                TextBox txt = sender as TextBox;
                if (e.KeyChar == 13)
                {
                    if (txt.Name == "txt_Ip")
                    {
                        txt_Port.Focus();
                    }
                    else if (txt.Name == "txt_Port")
                    {
                        txt_User.Focus();
                    }
                    else if (txt.Name == "txt_User")
                    {
                        txt_Pwd.Focus();
                    }
                    else if (txt.Name == "txt_Pwd")
                    {
                        btn_Conn.Focus();
                    }

                }
            }
        }

        private void btn_openTimer_Click(object sender, EventArgs e)
        {
            _timerTaskForm.ShowDialog();
        }
        private void InitialTray()
        {
            //隐藏主窗体  
            this.Hide();

            //实例化一个NotifyIcon对象  
            notifyIcon = new NotifyIcon();

            //托盘图标气泡显示的内容  
            notifyIcon.BalloonTipText = "正在后台运行";

            //托盘图标显示的内容  
            notifyIcon.Text = "代码生成器-定时任务";

            //注意：下面的路径可以是绝对路径、相对路径。但是需要注意的是：文件必须是一个.ico格式  
            //相对路径
            //这个是程序根目录下面的一张图片demo.ico
            string path = System.IO.Path.Combine((Application.StartupPath + @"\"), "favicon.ico");
            notifyIcon.Icon = new System.Drawing.Icon(path);

            //true表示在托盘区可见，false表示在托盘区不可见  
            notifyIcon.Visible = true;

            //气泡显示的时间（单位是毫秒）  
            notifyIcon.ShowBalloonTip(2000);
            notifyIcon.MouseClick += new System.Windows.Forms.MouseEventHandler(notifyIcon_MouseClick);

            ////设置二级菜单  
            //MenuItem setting1 = new MenuItem("二级菜单1");  
            //MenuItem setting2 = new MenuItem("二级菜单2");  
            //MenuItem setting = new MenuItem("一级菜单", new MenuItem[]{setting1,setting2});  

            //帮助选项，这里只是“有名无实”在菜单上只是显示，单击没有效果，可以参照下面的“退出菜单”实现单击事件  
            ToolStripMenuItem help = new ToolStripMenuItem("帮助");
            //关于选项  
            ToolStripMenuItem about = new ToolStripMenuItem("关于");
            //退出菜单项  
            ToolStripMenuItem exit = new ToolStripMenuItem("退出");
            exit.Click += new EventHandler(exit_Click);

            notifyIcon.ContextMenuStrip = new ContextMenuStrip();
            notifyIcon.ContextMenuStrip.Items.Add(help);
            notifyIcon.ContextMenuStrip.Items.Add(about);
            notifyIcon.ContextMenuStrip.Items.Add(exit);

            //窗体关闭时触发  
            this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing);
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            e.Cancel = true;
            //通过这里可以看出，这里的关闭其实不是真正意义上的“关闭”，而是将窗体隐藏，实现一个“伪关闭”  
            this.Hide();
        }

        /// <summary>  
        /// 鼠标单击  
        /// </summary>  
        /// <param name="sender"></param>  
        /// <param name="e"></param>  
        private void notifyIcon_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            //鼠标左键单击  
            if (e.Button == MouseButtons.Left)
            {
                //如果窗体是可见的，那么鼠标左击托盘区图标后，窗体为不可见  
                if (this.Visible == true)
                {
                    this.Visible = false;
                }
                else
                {
                    this.Visible = true;
                    this.Activate();
                }
            }
        }
        /// <summary>  
        /// 退出选项  
        /// </summary>  
        /// <param name="sender"></param>  
        /// <param name="e"></param>  
        private void exit_Click(object sender, EventArgs e)
        {
            //退出程序  
            System.Environment.Exit(0);
        }

        private void cb_start_CheckedChanged(object sender, EventArgs e)
        {
            try
            {
                string regPath = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run";
                string path = Application.ExecutablePath.ToLower();
                string name = Path.GetFileName(path);

                var regKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(regPath, true);

                if (regKey == null)
                    regKey = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(regPath);

                if (cb_start.Checked)
                {
                    // 如果复选框被选中，则设置自启动
                    regKey.SetValue(name, path);
                    _logger.LogInformation("程序设置开机自启动");
                }
                else
                {
                    // 如果复选框未被选中，则删除自启动项
                    if (regKey.GetValue(name) != null)
                    {
                        regKey.DeleteValue(name);
                        _logger.LogInformation("程序取消了开机自启动");
                    }
                }

            }
            catch (Exception ex)
            {
                // 最好记录或显示错误，而不是完全忽略它
                _logger.LogError("修改自启动设置失败: " + ex.Message);
            }
        }
        private void CheckAutoStartStatus()
        {
            try
            {
                string regPath = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run";
                string path = Application.ExecutablePath;
                string name = Path.GetFileName(path);

                using (var regKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(regPath))
                {
                    if (regKey != null)
                    {
                        // 检查当前程序是否在自启动项中
                        var regValue = regKey.GetValue(name) as string;
                        cb_start.Checked = (regValue != null && regValue.Equals(path, StringComparison.OrdinalIgnoreCase));
                    }
                    else
                    {
                        cb_start.Checked = false;
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.LogError("检测自启动状态失败: " + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                cb_start.Checked = false;
            }
        }

        private void btn_select_Click(object sender, EventArgs e)
        {
            DataTable dt = SQLHelper.GetTable($"select * from sys.tables where name like '%{txt_tableName.Text.Trim()}%'");
            lv_tables.Columns.Clear();
            lv_tables.Items.Clear();
            lv_tables.Columns.Add("表名", 200);
            foreach (DataRow dr in dt.Rows)
            {
                lv_tables.Items.Add(dr["name"].ToString());
            }
        }

        private void btn_SQLHelper_Click(object sender, EventArgs e)
        {
            CopyFile("SQLHelper.cs");
        }

        private void CopyFile(string fileName, string reptStr = "CodeSystem")
        {
            try
            {
                string sourceFile = Path.Combine(Environment.CurrentDirectory, "Helper", fileName);

                if (string.IsNullOrEmpty(txt_DataBaseName.Text.Trim()))
                {
                    MessageBox.Show("命名空间不能为空！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    _logger.LogError("命名空间不能为空！");
                    return;
                }

                // 检查源文件是否存在
                if (!File.Exists(sourceFile))
                {
                    MessageBox.Show(fileName + " 文件不存在！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    _logger.LogError(fileName + " 文件不存在！");
                    return;
                }

                SaveFileDialog saveFileDialog = new SaveFileDialog()
                {
                    FileName = fileName,
                    Filter = "C# 代码文件 (*.cs)|*.cs|所有文件 (*.*)|*.*", // 可选：添加文件类型筛选
                    Title = $"保存 {fileName} 文件"
                };

                if (saveFileDialog.ShowDialog() == DialogResult.OK)
                {
                    // 检查目标路径是否合法
                    if (string.IsNullOrWhiteSpace(saveFileDialog.FileName))
                    {
                        MessageBox.Show("无效的文件路径！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        _logger.LogError("无效的文件路径！");
                        return;
                    }

                    string sourceData = File.ReadAllText(sourceFile);
                    sourceData = sourceData.Replace(reptStr, txt_nameSpace.Text.Trim());
                    File.WriteAllText(saveFileDialog.FileName, sourceData);

                    MessageBox.Show("文件保存成功！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    _logger.LogInformation($"文件保存成功！源文件：{sourceFile}，目标文件：{saveFileDialog.FileName}");
                }
            }
            catch (UnauthorizedAccessException)
            {
                MessageBox.Show("无权限访问目标路径！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                _logger.LogError("无权访问目标路径！");
            }
            catch (IOException ex)
            {
                MessageBox.Show($"文件操作失败：{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                _logger.LogError($"文件操作失败：{ex.Message}");
            }
            catch (Exception ex)
            {
                MessageBox.Show($"发生未知错误：{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                _logger.LogError($"发生未知错误：{ex.Message}");
            }
        }

        private void btn_SQLiteHelper_Click(object sender, EventArgs e)
        {
            CopyFile("SQLiteHelper.cs");
        }

        private void btn_BaseBLL_Click(object sender, EventArgs e)
        {
            CopyFile("BaseBLL.cs");
        }

        private void btn_DateTime_Click(object sender, EventArgs e)
        {
            CopyFile("DateTimeHelper.cs");
        }

        private void btn_Hash_Click(object sender, EventArgs e)
        {
            CopyFile("HashHelper.cs");
        }

        private void btn_Http_Click(object sender, EventArgs e)
        {
            CopyFile("HttpHelper.cs");
        }
    }
}
